package com.franklin.java.configuration.sql.type.ui;


import com.franklin.java.api.ui.jpanel.AbstractComponent;
import com.franklin.java.api.ui.jpanel.MyJScrollPane;
import com.franklin.java.configuration.sql.type.SelectGroupState;
import com.franklin.java.entity.sql.TypeMapping;
import com.franklin.java.entity.group.TypeMappingGroup;
import com.franklin.java.icon.PluginIcons;
import com.franklin.java.utils.BeanUtils;
import com.franklin.java.utils.SwingUtils;
import com.franklin.plugins.common.utils.DataCheckUtils;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.InputValidator;
import com.intellij.openapi.ui.Messages;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.table.JBTable;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.util.ui.FormBuilder;
import org.apache.commons.lang3.ArrayUtils;

import javax.swing.*;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author Franklin
 * @since 2021/08/28 11:45
 */
public class TypeMappingComponent extends AbstractComponent {

    private JPanel mainPanel;
    private ComboBox<String> typeMappingComboBox;
    private JButton typeMappingCopyButton;
    private JBTable typeMappingTable;
    private MyJScrollPane myJScrollPane;
    private JButton addButton;
    private JButton removeButton;
    private JButton deleteButton;
    private boolean init;
    private TypeMappingModel typeMappingModel;
    private String curGroupName;
    private Map<String, TypeMappingGroup> groupNameMappingGroupMap;

    public TypeMappingComponent(String curGroupName, Map<String, TypeMappingGroup> groupNameMappingGroupMap) {
        this.curGroupName = curGroupName;
        this.groupNameMappingGroupMap = new LinkedHashMap<>(groupNameMappingGroupMap);
        createComponent();

        doInit();
    }

    @Override
    public JPanel getMainPanel() {
        return mainPanel;
    }

    public String getCurGroupName() {
        return curGroupName;
    }

    public Map<String, TypeMappingGroup> getGroupNameMappingGroupMap() {
        return groupNameMappingGroupMap;
    }

    private void doInit() {
        initAddButton();
        initRemoveButton();
        initTypeMappingComboBox();
        initTypeMappingCopyButton();
        initDeleteButton();
        initTable();

        initUi();
    }

    private void initUi() {
        //上半部分
        FormBuilder formBuilderUp = FormBuilder.createFormBuilder();
        GridLayoutManager upLayout = SwingUtils.createLayoutManager(1, 4);
        JPanel upPanel = formBuilderUp.getPanel();
        upPanel.setLayout(upLayout);
        upPanel.setBorder(BorderFactory.createLineBorder(JBColor.GRAY));
        addCell(upPanel,new JBLabel("类型映射组 : "),0,0,TypeMappingSizes.UpPanel.TITLE);
        addCell(upPanel,typeMappingComboBox,0,1,TypeMappingSizes.UpPanel.COMBOBOX);
        typeMappingCopyButton.setIcon(AllIcons.Actions.Copy);
        addCell(upPanel,typeMappingCopyButton,0,2,TypeMappingSizes.BTN);
        deleteButton.setIcon(AllIcons.General.Remove);
        addCell(upPanel,deleteButton,0,3,TypeMappingSizes.BTN);

        //主体
        GridLayoutManager mainLayout = SwingUtils.createLayoutManager(2, 1);
        mainPanel.setLayout(mainLayout);
        addCell(mainPanel,upPanel,0,0,TypeMappingSizes.UpPanel.SELF);


        typeMappingTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

        myJScrollPane = new MyJScrollPane(typeMappingTable);

        FormBuilder formBuilderDown = FormBuilder.createFormBuilder();
        JPanel downPanel = formBuilderDown.getPanel();
        GridLayoutManager downLayout = SwingUtils.createLayoutManager(1, 3);
        downPanel.setLayout(downLayout);
        addCell(downPanel, myJScrollPane,0,0,TypeMappingSizes.DownPanel.TABLE);
        addButton.setIcon(AllIcons.General.Add);
        addCell(downPanel,addButton,0,1,TypeMappingSizes.BTN);
        removeButton.setIcon(AllIcons.General.Remove);
        addCell(downPanel,removeButton,0,2,TypeMappingSizes.BTN);

        addCell(mainPanel,downPanel,1,0,TypeMappingSizes.DownPanel.SELF);
    }

    private void createComponent() {
        mainPanel = FormBuilder.createFormBuilder()
                .getPanel();
        typeMappingComboBox = new ComboBox<>();
        typeMappingCopyButton = new JButton();
        typeMappingTable = new JBTable();
        addButton = new JButton();
        removeButton = new JButton();
        deleteButton = new JButton();
    }

    private void initAddButton() {
        this.addButton.addActionListener(e -> {
            if (SelectGroupState.DEFAULT_GROUP.equals(this.curGroupName)){
                Messages.showWarningDialog("Can't Edit Default Group!", "Java Data Helper");
                return;
            }
            this.typeMappingModel.addRow(new TypeMapping("demoType", "java.lang.Object"));
        });
        this.addButton.setIcon(AllIcons.General.Add);
    }

    private void initRemoveButton() {
        this.removeButton.addActionListener(e -> {
            if (SelectGroupState.DEFAULT_GROUP.equals(this.curGroupName)){
                Messages.showWarningDialog("Can't Edit Default Group!", "Java Data Helper");
                return;
            }
            int[] selectedRows = this.typeMappingTable.getSelectedRows();
            if (ArrayUtils.isNotEmpty(selectedRows)) {
                if (SwingUtils.showConfirmDialog("Java Data Helper", "Confirm Delete Selected Items?")) {
                    for (int i = selectedRows.length - 1; i >= 0; i--) {
                        this.typeMappingModel.removeRow(selectedRows[i]);
                    }
                }
            }
        });
    }

    private void initTypeMappingComboBox() {
        this.typeMappingComboBox.addActionListener(e -> {
            if (this.init) {
                Object selected = this.typeMappingComboBox.getSelectedItem();
                if (Objects.nonNull(selected)) {
                    if (!this.curGroupName.equals(selected)) {
                        this.curGroupName = selected.toString();
                        this.refresh();
                    }
                }
            }
        });
    }

    private void initTypeMappingCopyButton() {
        this.typeMappingCopyButton.addActionListener(e -> {
            String value = SwingUtils.showInputDialog(
                    "Group Name:",
                    "Input Group Name:",
                    this.curGroupName + " Copy",
                    new InputValidator() {
                        public boolean checkInput(String inputString) {
                            return DataCheckUtils.isNotEmpty(inputString) && !TypeMappingComponent.this.groupNameMappingGroupMap.containsKey(inputString);
                        }

                        public boolean canClose(String inputString) {
                            return this.checkInput(inputString);
                        }
                    });
            if (DataCheckUtils.isNotEmpty(value)){
                //复制
                TypeMappingGroup typeMappingGroup = this.groupNameMappingGroupMap.get(this.curGroupName);
                typeMappingGroup = BeanUtils.clone(typeMappingGroup);
                if (Objects.nonNull(typeMappingGroup)) {
                    typeMappingGroup.setName(value);
                    this.curGroupName = value;
                    this.groupNameMappingGroupMap.put(value,typeMappingGroup);
                    this.refresh();
                }
            }
        });
    }

    private void initDeleteButton(){
        this.deleteButton.addActionListener(e -> {
            if (SwingUtils.showConfirmDialog("Java Data Helper","Confirm Delete Group " + this.typeMappingComboBox.getSelectedItem() + "?")){
                if (SelectGroupState.DEFAULT_GROUP.equals(this.curGroupName)){
                    Messages.showWarningDialog("Can't Delete Default Group!", "Java Data Helper");
                    return;
                }
                this.groupNameMappingGroupMap.remove(this.curGroupName);
                this.curGroupName = SelectGroupState.DEFAULT_GROUP;
                this.refresh();
            }
        });
    }

    private void initTable(){
        this.typeMappingModel = new TypeMappingModel();
        this.typeMappingTable.setModel(typeMappingModel);
        this.refresh();
    }

    private void refresh() {
        this.init = false;
        this.typeMappingComboBox.removeAllItems();
        Set<String> groupNames = this.groupNameMappingGroupMap.keySet();
        groupNames.forEach(this.typeMappingComboBox::addItem);
        this.typeMappingComboBox.setSelectedItem(this.curGroupName);
        this.typeMappingModel.refresh(
                this.groupNameMappingGroupMap.get(this.curGroupName).getElementList()
        );
        this.init = true;
    }



}
